package com.baitengsoft.patentservicemonitor.job.cloud.download;

import com.alibaba.fastjson.JSON;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.common.utils.IOUtils;
import com.aliyun.oss.model.ListObjectsRequest;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.OSSObjectSummary;
import com.aliyun.oss.model.ObjectListing;
import com.baitengsoft.patentservicemonitor.job.cloud.CloudStorageConfig;
import com.baitengsoft.patentservicemonitor.job.model.PacPatentinfoModel;
import com.baitengsoft.patentservicemonitor.job.service.PacPatentinfoService;
import com.baitengsoft.patentservicemonitor.job.utils.HttpUtils;
import com.baitengsoft.patentservicemonitor.job.utils.SysParametersUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author wangze
 * @date 2018-02-13 14:25.
 **/
public abstract class AbstractInitDataService {


    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    private static final Pattern NAMES = Pattern.compile("(.*?)([^/]+)/?$");
    @Autowired
    protected PacPatentinfoService pacPatentinfoService;

    @Autowired
    protected CloudStorageConfig config;


    @Autowired
    protected DataSource dataSource;

    @Autowired
    private SysParametersUtil sysParametersUtil;


    protected int maxThreads = 8;


    protected int getMaxFetchDataSize() {
        return 200;
    }

    protected boolean getIsRunRpt() {
        return false;
    }

    public OSSClient getOssClient() {
        return new OSSClient(config.getAliyunEndPoint(), config.getAliyunAccessKeyId(),
                config.getAliyunAccessKeySecret());
    }

    /**
     * 多线程获取oss 数据，插入数据(没有事务)
     *
     * @param pid
     */
    public boolean fetchData(Integer pid) {
        long startTime = System.currentTimeMillis();
        ExecutorService executorService = Executors.newFixedThreadPool(maxThreads);
        String keyPrefix = getFolder(pid);
        String nextMarker = null;
        OSSClient ossClient = this.getOssClient();
        ObjectListing objectListing;
        ListObjectsRequest listObjectsRequest = new ListObjectsRequest(config.getAliyunBucketName());
        listObjectsRequest.setPrefix(keyPrefix);
        do {
            objectListing = ossClient.listObjects(listObjectsRequest.withMarker(nextMarker).withMaxKeys(getMaxFetchDataSize()));
            List<OSSObjectSummary> sums = objectListing.getObjectSummaries();
            if (sums.size() == 0) {
                continue;
            }
            for (OSSObjectSummary s : sums) {
                executorService.submit(() -> {
                    OSSObject ossObject = ossClient.getObject(config.getAliyunBucketName(), s.getKey());
                    try {
                        String json = IOUtils.readStreamAsString(ossObject.getObjectContent(), "utf-8").replace("\"class\"" , "\"clazz\"");
                        dealData(pid, json, ossObject.getKey());
                    } catch (Exception e) {
                        System.out.println(e);
                        System.out.println("失败 " + s.getKey());
                        e.printStackTrace();
                    }
                });
            }
            nextMarker = objectListing.getNextMarker();
        } while (objectListing.isTruncated());
        executorService.shutdown();
        while (!executorService.isTerminated()) ;
        ossClient.shutdown();
        System.out.println((System.currentTimeMillis() - startTime) / 1000);

        //调用数据分析接口
        if (getIsRunRpt()) {
            excuteRun(pid);
        }

        fetchDataSuccessCallback(pid);
        return true;

    }


    /**
     * 多线程获取oss 数据， 事务批量插入数据(有事务)
     *
     * @param pid
     */
    public abstract void batchInsert(Integer pid);

    /**
     * 插入数据成功后，回调函数
     *
     * @param pid
     */
    public abstract void fetchDataSuccessCallback(Integer pid);


    /**
     * 获取oss文件夹
     *
     * @param platformId
     * @return
     */
    public abstract String getFolder(int platformId);


    /**
     * 处理oss获取的数据
     *
     * @param pid
     * @param json
     * @param key
     * @return
     */
    protected PacPatentinfoModel dealData(Integer pid, String json, String key) {
        PacPatentinfoModel p = JSON.parseObject(json, PacPatentinfoModel.class);
        if (p == null) {
            System.out.println(getName(key));
            logger.info(key);
            return null;
        }
        p.setPlatformid(pid);
        System.out.println(p.getAn());
        return p;
    }

    /**
     * 文件名
     */
    public String getName(String objectKey) {
        Matcher matcher = NAMES.matcher(objectKey);
        if (matcher.matches()) {
            return matcher.group(2);
        }
        return null;
    }


    /**
     * 调用接口，生成报表
     *
     * @param platformId
     */
    public void excuteRun(Integer platformId) {
        String url = sysParametersUtil.getAddOrUpdateRptUrl();
        HttpUtils.get(url + "?webPlatformId=" + platformId);

    }

}
